using System;
using System.Data;
using System.Text;
using System.Collections.Generic;

using BizElements.Core.ProviderComponents;

namespace BizElements.Core
{	
	/// <summary>
	/// Provides means to create any SQL function call.
	/// Format: "MyFunction(parameter1, parameter2)".
	/// </summary>
	[Serializable]
	public class Function : IRenderSql
	{
        #region CTor.

        /// <summary>
        /// Creates a new function.
        /// </summary>
        /// <param name="functionName">Function name.</param>
        /// <param name="alias">Alias. Often used when a function is used in a select list.</param>
        /// <param name="functionArguments">Function parameters.</param>
        /// <param name="returnType">Type of the value returned by function.</param>
        public Function(string functionName, string alias, IList<IRenderSql> functionArguments, Type returnType)
        {
            this.Name = functionName;
            this.FunctionArguments = functionArguments;
            this.Alias = alias;
            this.DataType = returnType;
            this.DbType = TypeUtil.DbTypeFrom(returnType);
        }

        #endregion

		#region Render.

		/// <summary>
		/// Renders function as SQL statement.
		/// </summary>
		/// <param name="dbms">Target DBMS.</param>
		/// <param name="output">StringBuilder to which SQL is appended.</param>
        /// <param name="parameters">SQL parameter collection to which the object's and its children's
		/// parameters are added. After the rendering is done the collection contains all parameters with unique names.</param>
        public virtual void Render(DbmsType dbms, StringBuilder output, DbParameterCollection parameters)
		{
            var renderer = DbmsComponentFactory.GetComponent<IFunctionRenderer>(dbms);
            renderer.Render(this, dbms, output, parameters);
		}

		#endregion

		#region Public and protected properties.

		/// <summary>Gets function name.</summary>
        public string Name { get; private set; }

		/// <summary>Gets alias. Often used when a function is used in a select list.</summary>
        public string Alias { get; private set; }

		/// <summary>Gets the SQL data type.</summary>
        public DbType DbType { get; private set; }

		/// <summary>Gets .NET type of data stored in the column.</summary>
        public Type DataType { get; private set; }

        /// <summary>Gets function parameters.</summary>
        protected internal IList<IRenderSql> FunctionArguments { get; private set; }

		#endregion        
	}
}
